package dyyx;

import java.util.Date;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class WatcherTest implements Watcher {

	private static final String CONNECT_ADDRES = "127.0.0.1:2181";
	private static final int SESSIONTIME = 2000;
	private static final CountDownLatch countDownLatch = new CountDownLatch(1);
	private ZooKeeper zk;

	public void createConnection(String connectAddres, int sessionTimeOut) throws Exception {
		zk = new ZooKeeper(connectAddres, sessionTimeOut, this);
		System.out.println("createConnection run ," + new Date());
		countDownLatch.await();
	}

	public boolean createPath(String path, String data) {
		try {
			this.exists(path, true);
			this.zk.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			System.out.println("create success,path=" + path + ",data=" + data);
			return true;
		} catch (Exception e) {
			System.out.println("create error," + e);
			return false;
		}
	}

	public Stat exists(String path, boolean needWatch) {
		try {
			return this.zk.exists(path, needWatch);
		} catch (Exception e) {
			System.out.println("exists error," + e);
			return null;
		}
	}

	public boolean updateNode(String path, String data) throws KeeperException, InterruptedException {
		exists(path, true);
		this.zk.setData(path, data.getBytes(), -1);
		return false;
	}

	public boolean deleteNode(String path) throws KeeperException, InterruptedException {
		exists(path, true);
		this.zk.delete(path, -1);
		return false;
	}

	public void process(WatchedEvent watchedEvent) {

		// 事件状态 
		Event.KeeperState keeperState = watchedEvent.getState();
		// 事件类型
		Event.EventType eventType = watchedEvent.getType();
		// zk 路径
		String path = watchedEvent.getPath();
		System.out.println("process watchedEvent," + watchedEvent);
		
		if (Event.KeeperState.SyncConnected == keeperState) {
            if (Event.EventType.None == eventType) {
                System.out.println("connection success");
                countDownLatch.countDown();
            } 
		}
		
	}

	public static void main(String[] args) throws Exception {
		WatcherTest test = new WatcherTest();
		test.createConnection(CONNECT_ADDRES, SESSIONTIME);
		test.createPath("/watchertest", "data");
		test.updateNode("/watchertest", "datanew");
		test.zk.getChildren("/watchertest", true);
		test.createPath("/watchertest/child", "child");
		test.deleteNode("/watchertest/child");
		test.deleteNode("/watchertest");
		
		test.createPath("/watchertest", "data2");
		test.updateNode("/watchertest", "data2new");
		
		test.createPath("/watchertest", "data3");
		test.updateNode("/watchertest", "data3new");
		
		Thread.sleep(1000);
		
		System.out.println("\n\n delete child test \n\n");

		test.createPath("/watchertest/child", "child");
		test.deleteNode("/watchertest/child");

	
		
		
		String path = "/watchertest";
		Thread.sleep(1000);
		System.out.println("\n\n update-no-watch \n\n");
		
		for(int i=0;i<3;i++){
			String data = "update-no-watch-"+i+","+new Date();
			test.zk.setData(path, data.getBytes(), -1);
		}
		
		Thread.sleep(1000);
		System.out.println("\n\n update-with-watch \n\n");
		
		for(int i=0;i<3;i++){
			String data = "update-with-watch-"+i+","+new Date();
			test.updateNode(path, data);
		}
		
		Thread.sleep(1000);
		System.out.println("\n\n update-with-duplicate-watch \n\n");
		
		for(int i=0;i<3;i++){
			test.exists(path, true);
			test.exists(path, true);
			String data = "update-with-duplicate-watch-"+i+","+new Date();
			test.zk.setData(path, data.getBytes(), -1);
		}
		
		Thread.sleep(1000);
		System.out.println("\n\n delete \n\n");
		
		
		test.deleteNode("/watchertest");
		// test.deleteNode("/watchertest/child");

		
		
	}
}